<template>
  <div id="cesiumContainer"></div>
  <!-- 切换新建筑 -->
  <button id="toggle-building">切换新建筑</button>
</template>

<script setup>
import {onMounted} from "vue";
import * as Cesium from 'cesium'
import {
  Cartesian3,
  createOsmBuildingsAsync,
  Ion,
  Math as CesiumMath,
  Terrain,
  Viewer,
  Color,
  IonResource, ClassificationType, Cesium3DTileset
} from 'cesium';
import "cesium/Build/Cesium/Widgets/widgets.css";


// 服务器上托管 CesiumJS 静态文件的 URL。
window.CESIUM_BASE_URL = '/Cesium';
// 您的访问令牌可在以下位置找到：https://ion.cesium.com/tokens。
// 将“your_access_token”替换为您的铯离子访问令牌。
Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyNjJhZWE3NC1iYjY2LTQwZjAtODc0YS0zZTdlMjRmNTE5ZDEiLCJpZCI6MjA1NjY1LCJpYXQiOjE3MTE5MzExMzB9.efKdT634nrROZLOR-GmU5gvPmnlCDsiHDTkCYlU4SXA';

/* 构建 3D 城市 */
async function build3DCity() {
  const viewer = new Viewer('cesiumContainer', {
    // 添加世界地形
    terrain: Terrain.fromWorldTerrain()
  });
  // 飞到指定笛卡尔坐标点
  viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(-104.9965, 39.74248, 4000)
  })
  // 添加 OSM buildings
  const buildingsTileset = await createOsmBuildingsAsync();
  viewer.scene.primitives.add(buildingsTileset)

  // 添加 GeoJSON 建筑
  async function addBuildingGeoJSON() {
    // 从 Cesium ion 加载 GeoJSON 文件.
    const geoJsonUri = await IonResource.fromAssetId(2523777);
    // 从 GeoJSON 创建几何图形，并将其夹紧到地面.
    const geoJson = await Cesium.GeoJsonDataSource.load(geoJsonUri, {clampToGround: true});
    // 将其添加到场景中。
    const dataSource = await viewer.dataSources.add(geoJson);
    // 默认情况下，CesiumJS 中的多边形将覆盖在场景中的所有 3D 内容上。
    // 修改多边形，使仅叠加到地形上，不叠加到 3D 建筑物上
    for (const entity of dataSource.entities.values) {
      entity.polygon.classificationType = ClassificationType.TERRAIN;
    }
    // 移动相机，使多边形在视野中。
    await viewer.flyTo(dataSource);
  }

  await addBuildingGeoJSON();

  // 使用 3D 图块样式语言隐藏此区域中的单个建筑物。
  buildingsTileset.style = new Cesium.Cesium3DTileStyle({
    // 创建样式规则以控制每个建筑物的“show”属性。
    show: {
      conditions: [
        // 任何具有此 elementId 的建筑物都将具有 'show = false'。
        // 小建筑物
        ['${elementId} === 332469316', false],
        ['${elementId} === 332469317', false],
        ['${elementId} === 235368665', false],
        ['${elementId} === 530288180', false],
        ['${elementId} === 530288179', false],
        // 大建筑物
        ['${elementId} === 532245203', false],
        // 如果建筑物没有这些 elementId 之一，请设置“show = true”。
        [true, true]
      ]
    },
    // 设置此特定 3D 图块集的默认颜色样式。
    // 对于任何具有`cesium#color`属性的建筑物，请使用该颜色，否则将其设置为白色。
    color: "Boolean(${feature['cesium#color']}) ? color(${feature['cesium#color']}) : color('#ffffff')"
  });

  // 将新建筑添加到场景中
  // 添加您从 Cesium ion 帐户创建的 3D 图块集。
  const newBuildingTileset = await Cesium3DTileset.fromIonAssetId(2523787);
  viewer.scene.primitives.add(newBuildingTileset);

  // 将相机移至新建筑物。
  await viewer.flyTo(newBuildingTileset);

  // 点击按钮切换新建筑（显隐）
  document.querySelector('#toggle-building').onclick = function() {
    newBuildingTileset.show = !newBuildingTileset.show;
  };

  // 考虑建筑物对周围环境的影响
}

onMounted(() => {
  build3DCity()
})
</script>

<style scoped>
#cesiumContainer {
  width: 100%;
  height: 100%;
}
#toggle-building { z-index: 1; position: fixed; top: 5px; left: 5px; }
</style>
